package query;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import document.InvertedIndex;

abstract public class BinaryOperand implements Query 
{
	@Override
	final public void process(InvertedIndex i) 
	{
		if(leftOperand.isNeutralQuery() && rightOperand.isNeutralQuery())
		{
			queryResult = new LinkedList<Integer>();
		}
		else if(leftOperand.isNeutralQuery())
		{
			rightOperand.process(i);
			queryResult = rightOperand.getResult();
		}
		else if(rightOperand.isNeutralQuery())
		{
			leftOperand.process(i);
			queryResult = leftOperand.getResult();
		}
		else
		{
			processOperands(i);
		}
	}
	
	@Override
	public boolean isNeutralQuery() 
	{
		return leftOperand.isNeutralQuery() && rightOperand.isNeutralQuery();
	}
	
	public void putLeftOperand(Query q)
	{
		leftOperand = q;
	}
	public void putRightOperand(Query q)
	{
		rightOperand = q;
	}
	
	@Override
	public int getOrder() {
		return 2;
	}
	
	@Override
	public List<Integer> getResult() 
	{
		return queryResult;
	}

	@Override
	public List<Query> getSubQueries() 
	{
		List<Query> result = new LinkedList<Query>();
		result.add(leftOperand);
		result.add(rightOperand);
		return result;
	}
	
	@Override
	public boolean isHomogenious() 
	{
		return (leftOperand.isHomogenious() && (leftOperand.getClass() == this.getClass()|| leftOperand instanceof Term ) ) && (rightOperand.isHomogenious()&& (rightOperand.getClass() == this.getClass()|| rightOperand instanceof Term ) ); 
	}
	
	@Override
	public List<Term> getLeaves() 
	{
		List<Term> rightList = rightOperand.getLeaves();
		List<Term> leftList = leftOperand.getLeaves();
		leftList.addAll(rightList);
		return leftList;
	}
	
	protected Query rebuild(InvertedIndex i, String operator, Comparator<Term> comp)
	{
		List<Term> leaves = getLeaves();
		for(Term t : leaves)
		{
			t.process(i);
		}
		Collections.sort(leaves, comp);
		StringBuffer query = new StringBuffer();
		int j=0;
		for(Term t: leaves)
		{
			query.append(t.getName());
			if(j < leaves.size()-1)
			{
				query.append(" "+operator+" ");
			}
			j++;
		}
		QueryBuilder qb = new QueryBuilder();
		qb.parse(query.toString());
		return qb.getQuery();
	}
	
	abstract public void processOperands(InvertedIndex i);
	
	protected Query leftOperand;
	protected Query rightOperand;
	protected List<Integer> queryResult;
}
